#pragma once
#include <Eigen/Eigen>
#include <algorithm>
#include <cmath>

namespace XRwy {
    template <class T>
    struct Type3 {
        T x, y, z;
    };

    using Float3 = Type3<float>;
    using Size3 = Type3<size_t>;

	namespace HairCoreMath {
		constexpr float HALF_SQRT_3 = 0.866025404f;

        inline bool is_colinear(Eigen::Vector3f ab, Eigen::Vector3f bc) {
            ab.normalize();
            bc.normalize();
            return std::abs(ab.dot(bc)) > 0.996194698f;
        }

		inline bool is_colinear(Eigen::Vector3f a, Eigen::Vector3f b, Eigen::Vector3f c) {
			return is_colinear(b - a, c - b);
		}

		//for a given (x,y,z), return the interpolation weight with the order of
		//(0,0,0) -> (0,0,1) -> ... -> (1,1,1)
		inline void trilinear_interpolation_values(float x, float y, float z, float ret[8]) {
			float _1_minus_x = 1 - x;
			float _1_minus_y = 1 - y;
			float _1_minus_z = 1 - z;
			for (size_t i = 0; i < 8; ++i)
				ret[i] = ( i & 1 ? z : _1_minus_z) * ( i & 2 ? y : _1_minus_y) * (i & 4 ? x : _1_minus_x);
		}
	};
}